﻿/**
 *┌──────────────────────────────────────────────────────────────┐
 *│ Copyright (c) 2024  All Right Reserved.
 *│ CLR 版本：4.0.30319.42000
 *│ 机器名称：HBWHYPW
 *│ 文件名称：LoginViewModel
 *│ 类 名 称：LoginViewModel
 *│ 命名空间：WinForm.ReactiveUI.UseSourceGenerators.ViewModels
 *└──────────────────────────────────────────────────────────────┘
 *┌──────────────────────────────────────────────────────────────┐
 *│ 创建时间：24-11-25 0:38
 *│ 创 建 人：杨彭伟
 *│ 修改时间：
 *│ 修 改 人：
 *│ 功能描述：
 *└──────────────────────────────────────────────────────────────┘
 */
using ReactiveUI;
using ReactiveUI.SourceGenerators;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;

namespace WinForm.ReactiveUI.UseSourceGenerators.ViewModels
{
    public partial class LoginViewModel : ReactiveObject
    {
        // 使用ReactiveUI.SourceGenerators，不需要手动实现属性变更通知
        [Reactive]
        public string? _username;
        [Reactive]
        public string? _password;
        // 创建一个 CompositeDisposable 实例来收集订阅
        private readonly CompositeDisposable _disposables = new CompositeDisposable();

        public ReactiveCommand<Unit, Unit> LoginCommand { get; }

        public LoginViewModel()
        {
            var canExecute = this.WhenAnyValue(
                x => x.Username,
                x => x.Password,
                (userName, password) =>
                    !string.IsNullOrEmpty(userName) &&
                    !string.IsNullOrEmpty(password));
            // 创建命令，它没有输出，也没有特定的错误类型
            LoginCommand = ReactiveCommand.CreateFromTask(async () =>
            {
                // 这里是登录逻辑，假设它返回一个bool表示登录是否成功
                bool success = await PerformLoginAsync(Username, Password);
                if (success)
                {
                    // 登录成功，更新UI或进行其他操作
                    // 注意：这里不要直接操作UI控件，因为我们在后台线程上
                }
                else
                {
                    // 登录失败，可以抛出异常或返回错误信息
                    throw new Exception("Login failed.");
                }
            }, canExecute);

            // 订阅命令的执行结果，并在UI线程上显示消息
            var subscription = LoginCommand
                .ObserveOn(RxApp.MainThreadScheduler) // 确保在主线程上执行
                .Subscribe(_ =>
                {
                    // 登录成功，这里可以安全地操作UI
                    MessageBox.Show("Login successful!");
                }, ex =>
                {
                    // 登录失败，这里可以安全地操作UI
                    MessageBox.Show(ex.Message);
                });

            subscription.DisposeWith(_disposables); // 确保订阅在ViewModel被销毁时取消
        }

        private async Task<bool> PerformLoginAsync(string username, string password)
        {
            // 模拟异步登录操作
            await Task.Delay(1000);
            // 这里应该是实际的登录验证逻辑
            return true; // 假设登录总是成功
        }

        // 当 ViewModel 被销毁时调用
        public void Dispose()
        {
            // 释放所有订阅
            _disposables.Dispose();
        }
    }
}
